最后一遍-L31-nextPermutation

LeetCode 31.nextPermutation

题目一开始完全没有看懂,也不知道什么是next Permutation。知道排列,但是不知道next Permutation 是什么。这道题目的难点,全部的在于理解题意,并且找到翻转的规律。

描述:

A permutation of an array of integers is an arrangement of its members into a sequence or linear order.

For example, for arr = [1,2,3], the following are all the permutations of arr: 
[1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].

The next permutation of an array of integers is the next lexicographically greater permutation of its integer.
 More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, 
 then the next permutation of that array is the permutation that follows it in the sorted container. 
 
 If such arrangement is not possible, the array must be rearranged as the lowest possible order 
 
 (i.e., sorted in ascending order).

For example, the next permutation of arr = [1,2,3] is [1,3,2].
Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
While the next permutation of arr = [3,2,1] is [1,2,3] 
because [3,2,1] does not have a lexicographical larger rearrangement.

Given an array of integers nums, find the next permutation of nums.

The replacement must be in place and use only constant extra memory.

Example 1:

Input: nums = [1,2,3]
Output: [1,3,2]
Example 2:

Input: nums = [3,2,1]
Output: [1,2,3]
Example 3:

Input: nums = [1,1,5]
Output: [1,5,1]
 

Constraints:

1 <= nums.length <= 100
0 <= nums[i] <= 100 

思路:

I don't think any one can understand this solution without seeing an example, 
here is an example:
2,3,6,5,4,1

Solution:
Step1, from right to left, // 从右到左,也就是从后到前,发现不是增加的元素
find the first number which not increase in a ascending order. 
In this case which is 3.

Step2, here we can have two situations: // 两种情况:一种是,没有发现,直接的翻转整个数组

one: We cannot find the number, all the numbers increasing in a ascending order. 
This means this permutation is the last permutation,
 we need to rotate back to the first permutation. 
 So we reverse the whole array, 
 for example, 6,5,4,3,2,1 we turn it to 1,2,3,4,5,6.

two: We can find the number, then the next step, // 另外一种情况是,右到左,也就是从后到前,发现比该元素大的元素,转换两个元素,并且把右面转换前的元素翻转
we will start from right most to leftward, 
try to find the first number which is larger than 3, 
in this case it is 4.
Then we swap 3 and 4, the list turn to 2,4,6,5,3,1.
Last, we reverse numbers on the right of 4,
we finally get 2,4,1,3,5,6.

Time complexity is: O(3*n)=O(n).

At the end, I don't know how to come up this solution. Here is just to understand the solution with example. Hope this helps.

代码:

public void nextPermutation(int[] nums) {
      int n = nums.length - 1, p = -1, pv = 0;
      // 从右到左,也就是从后到前,发现不是增序的元素
      for(int i = n - 1; i >= 0; i--){
        if(nums[i] < nums[i + 1]) {
            p = i;
            pv = nums[i];
            break;
        }
      }    
      
      //没有发现,直接的翻转整个数组
      if(p == -1) {
        reverse(nums, 0, n);
        return;
      }
      
      //发现后,右到左,也就是从后到前,发现比该元素大的元素,转换两个元素,
      for(int i = n; i >= 0; i--){
        if(nums[i] > pv){
          swap(nums, p, i);
          break;
        }
      }
      //并且把左面转换前的元素翻转
      reverse(nums, p + 1, n);
    }
    
    void reverse(int[] nums, int s, int e){
      while(s < e){
        swap(nums, s, e);
        s++;
        e--;
      }
    }
    
    void swap(int[] nums, int s, int e){
        int t = nums[s];
        nums[s] = nums[e];
        nums[e] = t;     
    }

Powered by andiHappy and Theme by AndiHappy